1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.struts2.components; 20 21 import com.opensymphony.xwork2.util.ValueStack; 22 import org.apache.logging.log4j.LogManager; 23 import org.apache.logging.log4j.Logger; 24 import org.apache.struts2.components.Param.UnnamedParametric; 25 import org.apache.struts2.util.AppendIteratorFilter; 26 import org.apache.struts2.util.MakeIterator; 27 import org.apache.struts2.views.annotations.StrutsTag; 28 import org.apache.struts2.views.annotations.StrutsTagAttribute; 29 30 import java.io.Writer; 31 import java.util.ArrayList; 32 import java.util.Iterator; 33 import java.util.List; 34 35 /** 36 * <!-- START SNIPPET: javadoc --> 37 * <p>Component for AppendIteratorTag, which jobs is to append iterators to form an 38 * appended iterator whereby entries goes from one iterator to another after each 39 * respective iterator is exhausted of entries.</p> 40 * 41 * <p>For example, if there are 3 iterator appended (each iterator has 3 entries), 42 * the following will be how the appended iterator entries will be arranged:</p> 43 * 44 * <ol> 45 * <li>First Entry of the First Iterator</li> 46 * <li>Second Entry of the First Iterator</li> 47 * <li>Third Entry of the First Iterator</li> 48 * <li>First Entry of the Second Iterator</li> 49 * <li>Second Entry of the Second Iterator</li> 50 * <li>Third Entry of the Second Iterator</li> 51 * <li>First Entry of the Third Iterator</li> 52 * <li>Second Entry of the Third Iterator</li> 53 * <li>Third Entry of the Third ITerator</li> 54 * </ol> 55 * <!-- END SNIPPET: javadoc --> 56 * 57 * <!-- START SNIPPET: params --> 58 * <ul> 59 * <li>var (String) - the name of which if supplied will have the resultant 60 * appended iterator stored under in the stack's context</li> 61 * </ul> 62 * <!-- END SNIPPET: params --> 63 * 64 * 65 * <!-- START SNIPPET: code --> 66 * public class AppendIteratorTagAction extends ActionSupport { 67 * 68 * private List myList1; 69 * private List myList2; 70 * private List myList3; 71 * 72 * 73 * public String execute() throws Exception { 74 * 75 * myList1 = new ArrayList(); 76 * myList1.add("1"); 77 * myList1.add("2"); 78 * myList1.add("3"); 79 * 80 * myList2 = new ArrayList(); 81 * myList2.add("a"); 82 * myList2.add("b"); 83 * myList2.add("c"); 84 * 85 * myList3 = new ArrayList(); 86 * myList3.add("A"); 87 * myList3.add("B"); 88 * myList3.add("C"); 89 * 90 * return "done"; 91 * } 92 * 93 * public List getMyList1() { return myList1; } 94 * public List getMyList2() { return myList2; } 95 * public List getMyList3() { return myList3; } 96 *} 97 * <!-- END SNIPPET: code --> 98 * 99 * <!-- START SNIPPET: example --> 100 * <s:append var="myAppendIterator"> 101 * <s:param value="%{myList1}" /> 102 * <s:param value="%{myList2}" /> 103 * <s:param value="%{myList3}" /> 104 * </s:append> 105 * <s:iterator value="%{#myAppendIterator}"> 106 * <s:property /> 107 * </s:iterator> 108 * <!-- END SNIPPET: example --> 109 * 110 * 111 * @see org.apache.struts2.util.AppendIteratorFilter 112 * @see org.apache.struts2.views.jsp.iterator.AppendIteratorTag 113 * 114 */ 115 @StrutsTag(name="append", tldTagClass="org.apache.struts2.views.jsp.iterator.AppendIteratorTag", description="Append the values of a list of iterators to one iterator") 116 public class AppendIterator extends ContextBean implements UnnamedParametric { 117 118 private static final Logger LOG = LogManager.getLogger(AppendIterator.class); 119 120 private AppendIteratorFilter appendIteratorFilter= null; 121 private List _parameters; 122 123 public AppendIterator(ValueStack stack) { 124 super(stack); 125 } 126 127 public boolean start(Writer writer) { 128 _parameters = new ArrayList(); 129 appendIteratorFilter = new AppendIteratorFilter(); 130 131 return super.start(writer); 132 } 133 134 public boolean end(Writer writer, String body) { 135 136 for (Iterator paramEntries = _parameters.iterator(); paramEntries.hasNext(); ) { 137 138 Object iteratorEntryObj = paramEntries.next(); 139 if (! MakeIterator.isIterable(iteratorEntryObj)) { 140 LOG.warn("param with value resolved as {} cannot be make as iterator, it will be ignored and hence will not appear in the merged iterator", iteratorEntryObj); 141 continue; 142 } 143 appendIteratorFilter.setSource(MakeIterator.convert(iteratorEntryObj)); 144 } 145 146 appendIteratorFilter.execute(); 147 148 putInContext(appendIteratorFilter); 149 150 appendIteratorFilter = null; 151 152 return super.end(writer, body); 153 } 154 155 // UnnamedParametric implementation -------------------------------------- 156 public void addParameter(Object value) { 157 _parameters.add(value); 158 } 159 160 @StrutsTagAttribute(description="The name of which if supplied will have the resultant appended iterator stored under in the stack's context") 161 public void setVar(String var) { 162 super.setVar(var); 163 } 164 } 165 166